//
//  IntersectionShape.cpp
//  Ray Tracer
//
//  Created by Kaila, Ashish on 4/12/13.
//  Copyright (c) 2013 Kaila, Ashish. All rights reserved.
//

#include "IntersectionShape.h"

// Returns true if an intersection occured, false otherwise.
bool IntersectionShape::intersect(Ray3D& ray,
                                  const Matrix4x4& worldToModel,
                                  const Matrix4x4& modelToWorld) const
{
    double minT = -1;
    Ray3D minRay;
    
    // The point of intersection is the point with smallest t value which is contained in all the shapes
    for (int i = 0; i < _childShapes.size(); i++)
    {
        // Clone ray so that all t values can be compared
        Ray3D clonedRay = ray;
        
        // Ray does not intersect one of the shapes, therefore does not lie in intersection space
        if (!intersectWithChildShape(clonedRay, i, worldToModel, modelToWorld))
        {
            return false;
        }
        
        // All shapes intersect with the point
        if (contains(clonedRay.intersection.point, worldToModel))
        {
            if ((minT < 0) || (clonedRay.intersection.t_value < minT))
            {
                minT = clonedRay.intersection.t_value;
                minRay = clonedRay;
            }
        }
    }
    
    if (minT >= 0)
    {
        // Ray struck intersection region, copy minRay to ray
        ray = minRay;
        return true;
    }
    
    return false;
}

// Returns true if world point is contained within the object
bool IntersectionShape::contains(const Point3D& worldPoint, const Matrix4x4& worldToModel) const
{
    int intersectionCount = 0;
    for (int i = 0; i < _childShapes.size(); i++)
    {
        if (pointContainedInChildShape(worldPoint, worldToModel, i))
        {
            intersectionCount++;
        }
    }
    
    // All shapes intersect with the point
    return (intersectionCount == _childShapes.size());
}